#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdint.h>

int open_tty()
{
    int fd, r;
    struct termios termio;

    memset (&termio, 0, sizeof (termio));

    if ((fd = open ("/dev/ttyUSB0", O_RDWR | O_NDELAY | O_NOCTTY)) == -1) {
        printf("Failed to open device\n");
        exit(-1);
    }

    fcntl(fd, F_SETFL, 0);
    r = tcgetattr(fd, &termio);

    /*
     *set the baud rate to 38400.
     */
    cfsetspeed(&termio, B115200);

    /*
     *set parity to none.
     */
    termio.c_cflag &= ~(PARENB | PARODD);

    /*
     *set databits to 8.
     */
    termio.c_cflag = ((termio.c_cflag & ~CSIZE) | CS8);

    /*
     *set flow control to none.
     */
    termio.c_cflag &= ~(CRTSCTS);
    termio.c_iflag &= ~(IXON | IXOFF | IXANY);
    termio.c_cflag |= (CLOCAL | CREAD);

    /*
     *apply our device config.
     */
    r = tcsetattr(fd, TCSANOW, &termio);

    if (r == -1) {
        printf("Failed to set termio options\n");
        exit(-1);
    }

    return fd;
}

typedef struct fpkt_s {
    char scode;
    char cmd;
    char param[4];
    char size[4];
    char flag;
    char csum;
    char ecode;
} fpkt_t;

char calculate_csum(fpkt_t pkt)
{
    char csum = 
        (pkt.scode + 
         pkt.cmd + 
         pkt.param[0] + 
         pkt.param[1] +
         pkt.param[2] +
         pkt.param[3] +
         pkt.size[0] + 
         pkt.size[1] +
         pkt.size[2] +
         pkt.size[3] +
         pkt.flag) % 0x100;

        return csum;
}

int main(int argc, char** argv)
{   
    int fd, rc;
    fpkt_t pkt, r_pkt = { 0x0 };

    pkt.scode = 0x40;
    pkt.cmd = 0x11;
    *(uint32_t*)(&pkt.param) = 0x0;
    *(uint32_t*)(&pkt.size) = 0x0;
    pkt.flag = 0x0;
    pkt.ecode = 0x0A;
    pkt.csum = calculate_csum(pkt);

    fd = open_tty();

    rc = write(fd, &pkt, sizeof(pkt));

    printf("%d bytes were written\n", rc);
    printf("reading ...\n", rc);

    while(1) {
        rc = read(fd, &r_pkt, sizeof(r_pkt));
        printf("%d bytes read\n\n", rc);
        printf("scode = 0x%x\ncmd = 0x%x\nparam = 0x%01x%01x%01x\n"
                "size = 0x04%01x%01x%01x\nflag = 0x%x\ncsum = 0x%x\necode = 0x%x\n",
                r_pkt.scode, r_pkt.cmd, 
                r_pkt.param[0], r_pkt.param[1], r_pkt.param[2], r_pkt.param[3], 
                r_pkt.size[0], r_pkt.size[1], r_pkt.size[2], r_pkt.size[3], 
                r_pkt.size, r_pkt.flag, r_pkt.csum, r_pkt.ecode);
    }

    close(fd);

    return 0;
}
